package cn.knet.sp.ncrm.modules.customer.importsupport;

import cn.knet.sp.ncrm.common.utils.IdGen;
import cn.knet.sp.ncrm.common.utils.IdUtils;
import cn.knet.sp.ncrm.common.utils.StringUtils;
import cn.knet.sp.ncrm.modules.customer.potentialcontactor.entity.PotentialContactor;
import cn.knet.sp.ncrm.modules.customer.potentialcontactor.service.PotentialContactorService;
import cn.knet.sp.ncrm.modules.customer.potentialcustomer.dao.PotentialCustomerAddinfoDao;
import cn.knet.sp.ncrm.modules.customer.potentialcustomer.dao.PotentialCustomerDao;
import cn.knet.sp.ncrm.modules.customer.potentialcustomer.dao.PotentialCustomerStatusDao;
import cn.knet.sp.ncrm.modules.customer.potentialcustomer.entity.PotentialCustomer;
import cn.knet.sp.ncrm.modules.customer.potentialcustomer.entity.PotentialCustomerAddinfo;
import cn.knet.sp.ncrm.modules.customer.potentialcustomer.entity.PotentialCustomerStatus;
import cn.knet.sp.ncrm.modules.customer.potentialcustomer.service.PotentialCustomerService;
import cn.knet.sp.ncrm.modules.customer.potentialcustomer.support.DistEnum;
import cn.knet.sp.ncrm.modules.sys.user.entity.User;
import cn.knet.sp.ncrm.modules.sys.utils.CustomerUtils;
import cn.knet.sp.ncrm.modules.sys.utils.UserUtils;

import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

/**
 * @INFO: 添加导入用户服务类
 * @Author: shishouyang
 * @Time: 2015/8/27 17:50
 */
@Service
@Transactional(readOnly = true)
public class ImportService {

	/**
	 * 持久层对象
	 */
	@Autowired
	protected PotentialCustomerDao dao;

	@Autowired
	protected PotentialCustomerStatusDao potentialCustomerStatusDao;

	@Autowired
	protected PotentialCustomerAddinfoDao addinfoDao;

	@Autowired
	protected PotentialContactorService potentialContactorService;

	/**
	 * 通过用户ID,回收用户数据
	 * 
	 * @param userId
	 *            用户ID
	 * @return
	 * @throws InvocationTargetException
	 * @throws IllegalAccessException
	 */
	@Transactional(readOnly = false)
	public void recoverByUserId(String userId) throws InvocationTargetException, IllegalAccessException {
		if (StringUtils.isNotBlank(userId)) {
			List<PotentialCustomer> privateList = new ArrayList<>();
			PotentialCustomer customerQuery = new PotentialCustomer();
			customerQuery.setDelFlag("0");
			customerQuery.setExecutorId(userId);
			List<PotentialCustomer> customerList = dao.findList(customerQuery);

			for (PotentialCustomer customer : customerList) {
				if ("private".equalsIgnoreCase(customer.getRecordVisibilityRule())) {
					privateList.add(customer);
				} else {
					customer.setRecordVisibilityRule("public");
					customer.setLastUpdated(new Date());
					// 更新新数据分配信息
					customer.setExecutorId(null);
					customer.setDistDate(null);
					customer.setDistUserId(null);
					customer.setDistStatus(DistEnum.UNDISTED.getValue());// 清除分配信息
					customer.clearGroup();// 清除用户分组
					dao.update(customer);
					// 重置子数据的分配状态和个人分组
					List<PotentialCustomer> subCustomerList = dao.findListByParentId(customer);
					if (null != subCustomerList && subCustomerList.size() > 0) {
						for (PotentialCustomer sub : subCustomerList) {
							sub.setRecordVisibilityRule("public");
							sub.setLastUpdated(new Date());
							// 更新新数据分配信息
							sub.setExecutorId(null);
							sub.setDistDate(null);
							sub.setDistUserId(null);
							sub.setDistStatus(DistEnum.UNDISTED.getValue());// 清除分配信息
							sub.clearGroup();// 清除用户分组
							dao.update(sub);
						}
					}
				}
			}
			this.recover(privateList);
		}
	}

	/**
	 * 回收数据
	 * 
	 * @param customerList
	 *            待回收的数据
	 * @return
	 * @throws InvocationTargetException
	 * @throws IllegalAccessException
	 */
	@Transactional(readOnly = false)
	public int recover(List<PotentialCustomer> customerList) throws InvocationTargetException, IllegalAccessException {
		int mergerNum = 0;
		for (PotentialCustomer customer : customerList) {
			PotentialCustomer existCustomer = getExistPotentialCustomer(customer);
			customer.setRecordVisibilityRule("public");
			customer.setLastUpdated(new Date());

			// 更新新数据分配信息
			customer.setExecutorId(null);
			customer.setDistDate(null);
			customer.setDistUserId(null);
			customer.setExecutorName(null);
			customer.setDistStatus(DistEnum.UNDISTED.getValue());// 清除分配信息
			customer.clearGroup();// 清除用户分组

			if (null == existCustomer) {
				dao.update(customer);
			} else {
				int existWeight = null == existCustomer.getWeight()
						|| StringUtils.isBlank(existCustomer.getWeight() + "") ? 0 : existCustomer.getWeight();
				int weight = null == customer.getWeight() || StringUtils.isBlank(customer.getWeight() + "") ? 0
						: customer.getWeight();

				if (existWeight >= weight) {
					customer.setParent(existCustomer);
					dao.update(customer);

					existCustomer.setMergerNum(existCustomer.getMergerNum() + 1);
					existCustomer.setNoReadMergerNum(existCustomer.getNoReadMergerNum() + 1);
					existCustomer.setDateMergerd(new Date());
					existCustomer.setLastUpdated(new Date());
					dao.update(existCustomer);
				} else {
					List<PotentialCustomer> subCustomerList = dao.findListByParentId(existCustomer);
					if (null != subCustomerList && subCustomerList.size() > 0) {
						for (PotentialCustomer sub : subCustomerList) {
							sub.setParent(customer);
							sub.setDateMergerd(new Date());
							sub.setLastUpdated(new Date());
							dao.update(sub);
						}
					}
					existCustomer.setParent(customer);
					existCustomer.setDateMergerd(new Date());
					existCustomer.setLastUpdated(new Date());
					dao.update(existCustomer);

					customer.setMergerNum(existCustomer.getMergerNum() + 1);
					customer.setNoReadMergerNum(existCustomer.getNoReadMergerNum() + 1);

					// 更新新数据分配信息
					customer.setExecutorId(existCustomer.getExecutorId());
					customer.setDistDate(existCustomer.getDistDate());
					customer.setDistUserId(existCustomer.getDistUserId());
					customer.setDistStatus(existCustomer.getDistStatus());

					customer.setDateMergerd(new Date());
					dao.update(customer);
				}
				mergerNum++;
			}
			//清除status 表中的其他分配状态 add by jief 20170219
			PotentialCustomerStatus status = new PotentialCustomerStatus();
			status.setFirsthandId(customer.getId());
			potentialCustomerStatusDao.deleteByFirstHandId(status);
		}

		return mergerNum;
	}

	/**
	 * 新回收数据 逐级向上层回收数据 add by jief 20170212
	 * 
	 * @param customerList
	 *            待回收的数据
	 * @return
	 * @throws InvocationTargetException
	 * @throws IllegalAccessException
	 */
	@Transactional(readOnly = false)
	public int newRecover(User recover_user, List<PotentialCustomer> customerList)
			throws InvocationTargetException, IllegalAccessException {
		int mergerNum = 0;
		// 如果是销售总监或销售经理
		if (CustomerUtils.USER_TYPE_MANAGER.equals(recover_user.getUserType())
				|| CustomerUtils.USER_TYPE_MANAGER.equals(recover_user.getUserType())) {
			for (PotentialCustomer customer : customerList) {
				// 更新原始数据状态
				PotentialCustomerStatus find_status = new PotentialCustomerStatus();
				find_status.setVisibilityUserId(recover_user.getId());
				find_status.setFirsthandId(customer.getId());
				List<PotentialCustomerStatus> pcss = potentialCustomerStatusDao.getByUserIdAndCustomerId(find_status);
				if (pcss != null && pcss.size() > 0) {
					PotentialCustomerStatus self_status = pcss.get(0);
					customer.setExecutorId(recover_user.getId());
					customer.setDistStatus(DistEnum.DISTED.getValue());
					customer.setDistDate(new Date());
					customer.setExecutorName(recover_user.getName());
					customer.setDistUserId(self_status.getParentId());
					dao.update(customer);
					// 修改自己的数据状态
					self_status.setDistStatus(DistEnum.UNDISTED.getValue());
					self_status.setExecutorId(null);
					self_status.setDistUserId(null);
					self_status.setExecutorName(null);
					potentialCustomerStatusDao.update(self_status);

					// 如果是销售经理要处理上一级的分配状态
					if (CustomerUtils.USER_TYPE_MANAGER.equals(recover_user.getUserType())) {
						PotentialCustomerStatus find_parent_status = new PotentialCustomerStatus();
						find_parent_status.setVisibilityUserId(self_status.getParentId());
						find_parent_status.setFirsthandId(customer.getId());
						List<PotentialCustomerStatus> parent_pcss = potentialCustomerStatusDao
								.getByUserIdAndCustomerId(find_parent_status);
						if (parent_pcss != null && parent_pcss.size() > 0) {
							PotentialCustomerStatus parent_status = parent_pcss.get(0);
							parent_status.setDistStatus(DistEnum.DISTED.getValue());
							parent_status.setExecutorId(recover_user.getId());
							parent_status.setDistDate(new Date());
							parent_status.setDistUserId(self_status.getParentId());
							parent_status.setExecutorName(recover_user.getName());
							potentialCustomerStatusDao.update(parent_status);
						}
						// 如果是销售总监则要将下一级的数据回收掉
					} else if (CustomerUtils.USER_TYPE_MANAGER.equals(recover_user.getUserType())) {
						PotentialCustomerStatus status = new PotentialCustomerStatus();
						status.setParentId(recover_user.getId());
						status.setFirsthandId(customer.getId());
						potentialCustomerStatusDao.deleteByParentIdAndCustomerId(status);
					}
				}
				mergerNum++;
			}
		} else {
			for (PotentialCustomer customer : customerList) {
				PotentialCustomer existCustomer = getExistPotentialCustomer(customer);
				customer.setRecordVisibilityRule("public");
				customer.setLastUpdated(new Date());
				// 更新新数据分配信息
				customer.setExecutorId(null);
				customer.setDistDate(null);
				customer.setDistUserId(null);
				customer.setExecutorName(null);
				customer.setDistStatus(DistEnum.UNDISTED.getValue());// 清除分配信息
				customer.clearGroup();// 清除用户分组

				if (null == existCustomer) {
					dao.update(customer);
				} else {
					int existWeight = null == existCustomer.getWeight()
							|| StringUtils.isBlank(existCustomer.getWeight() + "") ? 0 : existCustomer.getWeight();
					int weight = null == customer.getWeight() || StringUtils.isBlank(customer.getWeight() + "") ? 0
							: customer.getWeight();

					if (existWeight >= weight) {
						customer.setParent(existCustomer);
						dao.update(customer);

						existCustomer.setMergerNum(existCustomer.getMergerNum() + 1);
						existCustomer.setNoReadMergerNum(existCustomer.getNoReadMergerNum() + 1);
						existCustomer.setDateMergerd(new Date());
						existCustomer.setLastUpdated(new Date());
						dao.update(existCustomer);
					} else {
						List<PotentialCustomer> subCustomerList = dao.findListByParentId(existCustomer);
						if (null != subCustomerList && subCustomerList.size() > 0) {
							for (PotentialCustomer sub : subCustomerList) {
								sub.setParent(customer);
								sub.setDateMergerd(new Date());
								sub.setLastUpdated(new Date());
								dao.update(sub);
							}
						}
						existCustomer.setParent(customer);
						existCustomer.setDateMergerd(new Date());
						existCustomer.setLastUpdated(new Date());
						dao.update(existCustomer);

						customer.setMergerNum(existCustomer.getMergerNum() + 1);
						customer.setNoReadMergerNum(existCustomer.getNoReadMergerNum() + 1);

						// 更新新数据分配信息
						customer.setExecutorId(existCustomer.getExecutorId());
						customer.setDistDate(existCustomer.getDistDate());
						customer.setDistUserId(existCustomer.getDistUserId());
						customer.setDistStatus(existCustomer.getDistStatus());

						customer.setDateMergerd(new Date());
						dao.update(customer);
					}
				}
				PotentialCustomerStatus status = new PotentialCustomerStatus();
				status.setFirsthandId(customer.getId());
				potentialCustomerStatusDao.deleteByFirstHandId(status);
				mergerNum++;
			}
		}

		return mergerNum;
	}

	/**
	 * 保存数据
	 * 
	 * @param userWeight
	 *            用户的权重
	 * @param voList
	 *            添加导入的数据
	 * @param isMerger
	 *            是否合并
	 * @param flagStr
	 *            ID中的来源标识
	 * @return
	 * @throws InvocationTargetException
	 * @throws IllegalAccessException
	 */
	@Transactional(readOnly = false)
	public int save(List<ImportVO> voList, int userWeight, boolean isMerger, String flagStr)
			throws InvocationTargetException, IllegalAccessException {
		int mergerNum = 0;

		if (isMerger) {
			for (ImportVO vo : voList) {
				PotentialCustomer customer = new PotentialCustomer();
				PotentialCustomerAddinfo addinfo = new PotentialCustomerAddinfo();

				BeanUtils.copyProperties(customer, vo);
				BeanUtils.copyProperties(addinfo, vo);

				customer.setId(IdUtils.getInstanse().getUID(flagStr));
				addinfo.setId(IdGen.uuid());
				addinfo.setPotentialCustomerId(customer.getId());

				PotentialCustomer existCustomer = getExistPotentialCustomer(customer);

				// 插入一条联系人信息
				PotentialContactor contactor = new PotentialContactor();
				contactor.setPotentialCustomerId(customer.getId());
				contactor.setName(customer.getContactorName());
				contactor.setEmail(customer.getEmail());
				contactor.setMobile(customer.getMobile());
				contactor.setTelephone(customer.getTelephone());
				contactor.setWechat(customer.getContactorWechat());
				contactor.setQq(customer.getContactorQq());

				potentialContactorService.save(contactor);

				int weight = null == customer.getWeight() || StringUtils.isBlank(customer.getWeight() + "") ? 0
						: customer.getWeight() >= userWeight ? userWeight : customer.getWeight();
				customer.setWeight(weight);

				if (null == existCustomer) {
					dao.insert(customer);
					addinfoDao.insert(addinfo);
				} else {
					int existWeight = null == existCustomer.getWeight()
							|| StringUtils.isBlank(existCustomer.getWeight() + "") ? 0 : existCustomer.getWeight();

					if (existWeight >= weight) {
						customer.setParent(existCustomer);
						dao.insert(customer);
						addinfoDao.insert(addinfo);
						existCustomer.setMergerNum(existCustomer.getMergerNum() + 1);
						existCustomer.setNoReadMergerNum(existCustomer.getNoReadMergerNum() + 1);
						existCustomer.setDateMergerd(new Date());
						existCustomer.setLastUpdated(new Date());
						dao.update(existCustomer);
					} else {
						List<PotentialCustomer> subCustomerList = dao.findListByParentId(existCustomer);
						if (null != subCustomerList && subCustomerList.size() > 0) {
							for (PotentialCustomer sub : subCustomerList) {
								sub.setParent(customer);
								sub.setDateMergerd(new Date());
								sub.setLastUpdated(new Date());
								dao.update(sub);
							}
						}
						existCustomer.setParent(customer);
						existCustomer.setDateMergerd(new Date());
						existCustomer.setLastUpdated(new Date());
						dao.update(existCustomer);
						customer.setMergerNum(existCustomer.getMergerNum() + 1);
						customer.setNoReadMergerNum(existCustomer.getNoReadMergerNum() + 1);

						// 更新新数据分配信息
						customer.setExecutorId(existCustomer.getExecutorId());
						customer.setDistDate(existCustomer.getDistDate());
						customer.setDistUserId(existCustomer.getDistUserId());
						customer.setDistStatus(existCustomer.getDistStatus());

						customer.setDateMergerd(new Date());
						customer.setLastUpdated(new Date());
						dao.insert(customer);
						addinfoDao.insert(addinfo);
					}
					mergerNum++;
				}
			}

		} else {
			for (ImportVO vo : voList) {
				PotentialCustomer customer = new PotentialCustomer();
				PotentialCustomerAddinfo addinfo = new PotentialCustomerAddinfo();

				BeanUtils.copyProperties(customer, vo);
				BeanUtils.copyProperties(addinfo, vo);

				int weight = null == customer.getWeight() || StringUtils.isBlank(customer.getWeight() + "") ? 0
						: customer.getWeight() >= userWeight ? userWeight : customer.getWeight();
				customer.setWeight(weight);
				customer.setId(IdUtils.getInstanse().getUID(flagStr));
				addinfo.setId(IdGen.uuid());
				addinfo.setPotentialCustomerId(customer.getId());

				// 插入一条联系人信息
				PotentialContactor contactor = new PotentialContactor();
				contactor.setPotentialCustomerId(customer.getId());
				contactor.setName(customer.getContactorName());
				contactor.setEmail(customer.getEmail());
				contactor.setMobile(customer.getMobile());
				contactor.setTelephone(customer.getTelephone());
				contactor.setWechat(customer.getContactorWechat());
				contactor.setQq(customer.getContactorQq());

				potentialContactorService.save(contactor);

				dao.insert(customer);
				addinfoDao.insert(addinfo);
			}
		}

		return mergerNum;
	}

	/**
	 * 获取数据库中已存在的重复的主数据
	 * 
	 * @param customer
	 * @return
	 */
	private PotentialCustomer getExistPotentialCustomer(PotentialCustomer customer) {
		PotentialCustomer customerTemp = null;
		List<PotentialCustomer> tempList = null;

		/**
		 * 公司名
		 */
		if (StringUtils.isNotBlank(customer.getCorporationName())) {
			customerTemp = new PotentialCustomer();
			customerTemp.setId(customer.getId());
			customerTemp.setCorporationName(customer.getCorporationName());
			tempList = dao.findListByParentIdIsNull(customerTemp);
			if (null != tempList && tempList.size() > 0) {
				return tempList.get(0);
			}
		}

		/**
		 * 公司URL
		 */
		if (StringUtils.isNotBlank(customer.getCorporationUrl())) {
			customerTemp = new PotentialCustomer();
			customerTemp.setId(customer.getId());
			customerTemp.setCorporationUrl(customer.getCorporationUrl());
			tempList = dao.findListByParentIdIsNull(customerTemp);
			if (null != tempList && tempList.size() > 0) {
				return tempList.get(0);
			}
		}

		/**
		 * 联系人
		 */
		/*
		 * if (StringUtils.isNotBlank(customer.getContactorName())) {
		 * customerTemp = new PotentialCustomer();
		 * customerTemp.setId(customer.getId());
		 * customerTemp.setContactorName(customer.getContactorName()); tempList
		 * = dao.findListByParentIdIsNull(customerTemp); if (null != tempList &&
		 * tempList.size() > 0) { return tempList.get(0); } }
		 */

		/**
		 * 手机
		 */
		if (StringUtils.isNotBlank(customer.getMobile())) {
			customerTemp = new PotentialCustomer();
			customerTemp.setId(customer.getId());
			customerTemp.setMobile(customer.getMobile());
			tempList = dao.findListByParentIdIsNull(customerTemp);
			if (null != tempList && tempList.size() > 0) {
				return tempList.get(0);
			}
		}

		/**
		 * 电话
		 */
		if (StringUtils.isNotBlank(customer.getTelephone())) {
			customerTemp = new PotentialCustomer();
			customerTemp.setId(customer.getId());
			customerTemp.setTelephone(customer.getTelephone());
			tempList = dao.findListByParentIdIsNull(customerTemp);
			if (null != tempList && tempList.size() > 0) {
				return tempList.get(0);
			}
		}

		return null;
	}

}
